<!-- index.vue -->
<template>
  <div class="demo-image__preview">
    <el-image
      :src="url"
      :fit="fit"
      :style="imageStyle"
      :preview-src-list="realSrcList"
      :initial-index="1"
      preview-teleported
      hide-on-click-modal
      lazy
    >
      <template v-for="(value, name) in $slots" :key="name" #[name]="slotData">
        <slot :name="name" v-bind="slotData || {}"></slot>
      </template>
      <template #error>
        <div class="image-slot">
          <el-image
            src="https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png"
          />
        </div>
      </template>
    </el-image>
  </div>
</template>

<script setup>
import { computed, onMounted } from "vue";
import { isExternal } from "@/utils/validate.js";

const props = defineProps({
  src: {
    type: [String, Array], // 允许两种类型
    default: "",
    validator(value) {
      return typeof value === "string" || Array.isArray(value);
    },
  },
  width: {
    type: [Number, String],
    default: "100%",
  },
  height: {
    type: [Number, String],
    default: "100%",
  },
  fit: {
    type: String,
    default: "cover",
    validator(value) {
      return ["contain", "cover", "fill", "none", "scale-down"].includes(value);
    },
  },
  assetPrefix: {
    type: String,
    default: "assets/file",
  },
});

const imageStyle = computed(() => ({
  width: props.width,
  height: props.height,
}));

// 封面图片
const url = computed(() => {
  //获取路径
  return getAssetsFile(props.src);
});
// 预览数组
const realSrcList = computed(() => {
  // console.log("realSrcList", processPaths(props.src));
  return processPaths(props.src);
});
// 处理单个路径
const processSinglePath = (path) => {
  if (!path) return "";
  // 正确处理外部链接
  if (isExternal(path)) {
    // console.log("是外链", path);
    return path;
  }
  // console.log("不是外链", path);
  // 处理数组逻辑

  const parts = path.split("/");
  const type = parts[parts.length - 2];
  const name = parts[parts.length - 1];
  if (!type || !name) return ""; // 格式不合法则返回空
  return new URL(`../../${props.assetPrefix}/${type}/${name}`, import.meta.url)
    .href;
};

// 处理输入为字符串或数组
const processPaths = (input) => {
  if (!input) return [];
  // 仅对字符串尝试解析
  if (typeof input === "string") {
    try {
      // console.log("尝试解析为数组");
      input = JSON.parse(input);
    } catch (e) {
      // 解析失败则直接返回原字符串路径
      return [processSinglePath(input.trim())].filter(Boolean);
    }
  }
  if (Array.isArray(input)) {
    return input
      .map(processSinglePath)
      .filter(Boolean) // 过滤空路径
      .filter((path) => path.length > 0); // 过滤空字符串
  }
  return [];
};

const isValidPath = (path) => {
  if (!path) return false;
  if (isExternal(path)) return true; // 外链直接通过验证
  const parts = path.split("/");
  return parts.length >= 2; // 至少包含文件名即可（如：["type", "name.jpg"]）
};

// 获取展示的图片的路径
const getAssetsFile = () => {
  let input = props.src;
  if (!input) return "";
  // 仅对字符串尝试解析
  if (typeof input === "string") {
    try {
      // console.log("尝试解析为数组");
      input = JSON.parse(input);
    } catch (e) {
      // 解析失败则直接返回原字符串路径
      return processSinglePath(input.trim());
    }
  }
  // console.log("props.src 类型：", typeof input);
  // console.log("isArray", Array.isArray(input));

  if (Array.isArray(input)) {
    // console.log("数组：", input);
    // 找到数组中首个非空且有效的路径
    const firstValidPath = input.find((path) => {
      const processed = processSinglePath(path);
      return processed && processed.length > 0;
    });
    return firstValidPath ? processSinglePath(firstValidPath) : "";
  } else {
    return processSinglePath(input);
  }
};
</script>

<style lang="scss" scoped>
.image-container {
  border-radius: 5px;
  background-color: #ebeef5;
  box-shadow: 0 0 5px 1px #ccc;
  transition: all 0.3s;
  cursor: pointer;
  &:hover {
    transform: scale(1.2);
  }
}

.el-image {
  @extend .image-container;
  :deep(.el-image__inner) {
    width: 100%;
    height: 100%;
  }
}

.file-error {
  @extend .image-container;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #909399;
  font-size: 14px;
}
</style>
